package com.demo.behavioral.visitor;

import java.util.ArrayList;
import java.util.List;

/**
 * 访问者模式
 * 访问者模式把数据结构和作用于结构上的操作解耦合，使得操作集合可相对自由地演化。
 * 访问者模式适用于数据结构相对稳定算法又易变化的系统。因为访问者模式使得算法操作增加变得容易。
 * 访问者模式将有关行为集中到一个访问者对象中，其改变不影响系统数据结构，但这时访问者对象就需要多次修改，相对违背了开闭原则。
 * 实现方法：1.定义一个抽象访问者及其实现类，在重载的visit函数中声明访问者可以访问的对象，该函数就是整个设计模式的核心。
 * 2、定义一个抽象元素（即被访问者），提供重载的accept函数接收抽象访问者，然后实现多个实现类，accept方法具体为visitor.visit(this)
 * @author allen
 *
 */
public class Test {
	
	public static void main(String[] args) {
		//以HR系统统计筛选简历这个故事为例，抽象访问者就是HR系统，抽象元素就是学生简历
		//一开始的需求就是统计全部人数总数
		//定义HR系统
		ResumeHandler resumeHandler = new ResumeHandler();
		//初始化多个个简历信息
		List<Resume> resumes = new ArrayList<Resume>();
		Resume undergraduateResume = new UndergraduateResume();
		undergraduateResume.setUniversity("中大"); 
		resumes.add(undergraduateResume);
		undergraduateResume = new UndergraduateResume();
		undergraduateResume.setUniversity("华工"); 
		resumes.add(undergraduateResume);
		Resume masterResume = new MasterResume();
		masterResume.setUniversity("北大");
		resumes.add(masterResume);
		
		//将所有简历与HR系统关联，这里隐藏了全部HR系统操作
		for(Resume resume:resumes){
			//原设计模式自己的设计
			resume.accept(resumeHandler);
			//实际上visit可以代替accept，可读性会更好
//			resumeHandler.visit(resume);
		}  
		
		//得到最后结果
		System.out.println("简历总数："+resumeHandler.getResumeNum());
		
		//然后又接着改需求，要统计全部北大人数
		//如果出现需求变化，只需在resumeHandler作修改即可
		System.out.println("北大简历总数："+resumeHandler.getPeiKingNum());
	}

}
